<?php

namespace App\Http\Services\Meeting;

use App\Http\Model\Meet;
use App\Http\Model\MeetRule;
use App\Http\Model\MeetSayHiLogs;
use App\Http\Model\Origami\OrigamiType;
use App\Http\Model\Origami\UserOrigami;
use App\Http\Model\PriorityMatchUserIds;
use App\Http\Model\Room;
use App\Http\Model\RoomUser;
use App\Http\Model\Trends;
use App\Http\Model\User;
use App\Http\Services\CommonServices;
use App\Http\Services\UserTagServices;
use Illuminate\Support\Facades\Log;

/**
 * 扩列-在线用户列表
 *
 * Created on 2021/10/19 16:31
 * @Author <yuxiang.zhu@asiainnovations.net>
 */
class MeetingServices extends CommonServices
{
    /**
     * user表
     *
     * @var User
     */
    private $userModel;

    /**
     * @var RoomUser
     */
    private $roomUserModel;

    /**
     * 动态
     *
     * @var Trends
     */
    private $trendsModel;

    /**
     * say hello
     *
     * @var MeetSayHiLogs
     */
    private $sayHiLogModel;

    /**
     * 交友折纸
     *
     * @var UserOrigami
     */
    private $userOrigamiModel;

    /**
     * 优先匹配model
     *
     * @var PriorityMatchUserIds
     */
    private $priorityMatchUserIdsModel;

    /**
     * 用户标签
     *
     * @var UserTagServices
     */
    private $userTagService;

    /**
     * 折纸类型
     *
     * @var []
     */
    private $origamiTypes;

    /**
     * 获取在线用户列表
     *
     * @param int $loginUserId 当前登录用户id
     * @param int $gender 根据性别查询 0=全部 1=男 2=女
     * @param int $page
     * @return array
     */
    public function getUserListV2(int $loginUserId, int $gender, int $page): array
    {
        $gender = $this->getGender($loginUserId, $gender);
        $result = ['list' => [], 'page' => $page - 1];
        $meetModel = new Meet();
        $meetRules = MeetRule::query()->orderByDesc('min_score')->get()->toArray();
        if (!$meetRules) {//没有规则
            $limitStage4 = 2;
            $limitStage3 = 10;
            $limitStage2 = 20;
            $limitStage1 = 8;
            $level4UserIds = $meetModel->randomGetOnlineUserIdsByLevel(4, $limitStage4, $gender);
            $result['expect_stage_4'] = $limitStage4;
            $total = count($level4UserIds);//总数
            $result['list'] = $this->getUserInfoByUserIds($level4UserIds, $loginUserId);
            if ($total < $limitStage4) {//数量不足
                $result['real_stage_4'] = $total;
                $limitStage3 += ($limitStage4 - $total);//去下一阶段取
            }

            $level3UserIds = $meetModel->randomGetOnlineUserIdsByLevel(3, $limitStage3, $gender);
            $result['expect_stage_3'] = $limitStage3;
            $total = count($level3UserIds);//总数
            $result['list'] = array_merge($result['list'], $this->getUserInfoByUserIds($level3UserIds, $loginUserId));
            if ($total < $limitStage3) {//数量不足
                $result['real_stage_3'] = $total;
                $limitStage2 += ($limitStage3 - $total);//去下一阶段取
            }

            $level2UserIds = $meetModel->randomGetOnlineUserIdsByLevel(2, $limitStage2, $gender);
            $result['expect_stage_2'] = $limitStage2;
            $total = count($level2UserIds);//总数
            $result['list'] = array_merge($result['list'], $this->getUserInfoByUserIds($level2UserIds, $loginUserId));
            if ($total < $limitStage2) {//数量不足
                $result['real_stage_2'] = $total;
                $limitStage1 += ($limitStage2 - $total);//去下一阶段取
            }

            $level1UserIds = $meetModel->randomGetOnlineUserIdsByLevel(1, $limitStage1, $gender);
            $result['expect_stage_1'] = $limitStage1;
            $total = count($level1UserIds);//总数
            $result['list'] = array_merge($result['list'], $this->getUserInfoByUserIds($level1UserIds, $loginUserId));
            if ($total < $limitStage1) {//数量不足
                $result['real_stage_1'] = $total;
            }
        } else {//有规则
            $ruleNumber = count($meetRules);
            $plusNumber = 0;
            foreach ($meetRules as $meetRule) {
                $limitNum = $meetRule['user_num'] + $plusNumber;
                $plusNumber = 0;
                $userIds = $meetModel->randomGetOnlineUserIdsByLevel($ruleNumber, $limitNum, $gender);
                $result['expect_stage_' . $ruleNumber] = $limitNum;
                $total = count($userIds);//总数
                $result['list'] = array_merge($result['list'], $this->getUserInfoByUserIds($userIds, $loginUserId));
                $result['real_stage_' . $ruleNumber] = $total;
                if ($total < $limitNum) {//数量不足
                    $plusNumber += ($limitNum - $total);//去下一阶段取
                }

                $ruleNumber--;
            }
        }

        //过滤掉自己
        if ($result['list']) {
            $tempList = [];
            $allUserIds = [];
            foreach ($result['list'] as $item) {
                if ($item['user_id'] != $loginUserId && !in_array($item['user_id'], $allUserIds)) {//过滤登录人和重复的user_id
                    $tempList[] = $item;
                    $allUserIds[] = $item['user_id'];
                }
            }
            $result['list'] = $tempList;
        }

        $result['list_number'] = count($result['list']);
        return $result;
    }

    /**
     * 获取用户详细信息
     *
     * Created at 2021/10/20 18:51
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param array $userIds
     * @param int $loginUserId
     * @return array
     */
    private function getUserInfoByUserIds(array $userIds, int $loginUserId): array
    {
        $list = [];
        foreach ($userIds as $userId) {
            $list[] = $this->getMeetUserInfo($userId, $loginUserId);
        }
        return $list;
    }

    /**
     * 随机一个下标
     *
     * Created at 2021/10/18 18:49
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param int $total
     * @return int
     */
    private function getRandIndex(int $total): int
    {
        return rand(0, $total - 1);
    }

    /**
     * 获取用户信息
     *
     * @param int $userId
     * @param int $loginUserId
     * @return array
     */
    public function getMeetUserInfo(int $userId, int $loginUserId): array
    {
        $this->userModel = new User();
        $this->origamiTypes = collect(OrigamiType::getTypes())->keyBy('id')->toArray();
        $this->roomUserModel = new RoomUser();
        $this->trendsModel = new Trends();
        $this->userOrigamiModel = new UserOrigami();
        $this->sayHiLogModel = new MeetSayHiLogs();
        $this->priorityMatchUserIdsModel = new PriorityMatchUserIds();
        $this->userTagService = new UserTagServices();
        $userInfo = $this->userModel->get_user($userId);//用户信息
        $userInfo['online'] = intval($this->userModel->checkUserOnlineStatus($userId));//1=在线 0=不在线
        $score = 30;//用户得分, 在线+30分
        $newUser = $userInfo['user_cat'] ?? 0;
        if ($newUser == 1) {
            $score += 20;//新用户+20
        }

        //是否发布过交友折纸
        $userOrigami = $this->userOrigamiModel->getUserOrigami($userId);
        if ($userOrigami && $userOrigami['status'] == UserOrigami::STATUS_OF_PUBLISHED && $userOrigami['audit_status'] == UserOrigami::AUDIT_STATUS_OF_AUDIT_SUCCESS) {//审核通过
            $score += 40;
            $typeName = $this->origamiTypes[$userOrigami['type_id']]['name'] ?? '';
            $userInfo['user_origami'] = ['content' => $userOrigami['content'], 'origami_type_name' => $typeName,
                'type_id' => $userOrigami['type_id']];
            $createdAt = $userOrigami['created_at'];
            if ($createdAt <= 600) {//10分钟内
                $score += 30;
            } elseif ($createdAt <= 1200) {//30分钟之内
                $score += 20;
            } elseif ($createdAt <= 3600) {//60分钟之内
                $score += 10;
            }
        }

        $completion = 0;//基本信息
        $quotas = ['affective_state' => 10, 'home' => 10, 'occupation' => 10, 'height' => 10];
        foreach ($quotas as $key => $num) {
            if (isset($userInfo[$key]) && $userInfo[$key]) {
                $completion += $num;
            }
        }

        if ($completion >= 30) {
            $score += 30;
        } elseif ($completion >= 10 && $completion <= 20) {
            $score += 10;
        }

        if (!isset($userInfo['user_origami'])) {//动态
            $trends = $this->trendsModel->getLatelyTrendsFromCache($userId);
            if ($trends) {
                $userInfo['trends'] = $trends;
            }
        }

        $tags = $userInfo['tags'] ?? [];//我的标签
        if ($tags && !isset($userInfo['user_origami']) && !isset($userInfo['trends'])) {
            $userInfo['tag_names'] = $this->userTagService->getUserTagNamesFromCache($userId, $tags);
        }

        if (!$tags) {
            $tags = $userInfo['other_tags'] ?? [];//他人标签
        }

        if ($tags) {
            $score += 20;//有标签+20
        }

        $trend = $this->trendsModel->checkUserTrends($userId);//动态
        if ($trend) {
            $score += 40;//动态+40
        }

        $userInfo['room_id'] = null;
        $userRoomId = intval($this->roomUserModel->get_user_cur_room($userId));
        if ($userRoomId) {
            $userInfo['room_id'] = $userRoomId;
            $score += 20;
        }

        $recommend = $this->priorityMatchUserIdsModel->checkExist($userId);//是否是后台推荐
        if ($recommend) {
            $score += 100;
        }

        $userInfo['score'] = $score;
        $userInfo['level'] = $this->getLevel($score);
        $userInfo['say_hello'] = intval($this->sayHiLogModel->getSayHiLog($loginUserId, $userId));//1=可以say hello
        $userInfo['random_msg'] = $this->getRandomMsg();//随机文案
        unset($userInfo['tags'], $userInfo['other_tags'], $userInfo['channel_id'], $userInfo['guid'], $userInfo['code']);
        return $userInfo;
    }

    /**
     * 根据分数获取level
     *
     * Created at 2021/10/20 18:27
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param $score
     * @return int
     */
    public function getLevel($score): int
    {
        $meetRules = MeetRule::query()->orderBy('min_score')->get()->toArray();//按分数从小到大取
        $level = 1;
        if (!$meetRules) {
            if ($score >= 70 && $score <= 99) {
                $level = 2;
            } elseif ($score >= 100 && $score <= 199) {
                $level = 3;
            } elseif ($score >= 200) {
                $level = 4;
            }

            return $level;
        }

        foreach ($meetRules as $index => $meetRule) {
            if ($meetRule['min_score'] >= 0 && $meetRule['max_score'] == 0) {
                $meetRule['max_score'] = 1000;//设置默认值
            }

            if ($score >= $meetRule['min_score'] && $score <= $meetRule['max_score']) {
                $level = $index + 1;
            }
        }

        return $level;
    }

    /**
     * 随机获取一条文案
     *
     * @return string
     */
    private function getRandomMsg(): string
    {
        $messages = [
            '这个人有点点神秘噢，戳他了解一下',
            '他连签名也懒得写，感觉你俩挺合适',
            '不是吧不是吧，有趣到文字无法描述了吗',
            '你猜我是个什么样的可爱怪？',
            '据说他沉迷发折纸，忘了发动态...',
            '有些人注定是个谜，你也许刚好有谜底',
            '听说好奇的人在这里容易交到朋友？',
            '这里曾荒芜，后来你来了，奇迹般万物生长',
        ];

        return $messages[rand(0, count($messages) - 1)];
    }

    /**
     * @param int $loginUserId
     * @param int $gender
     * @return int
     */
    private function getGender(int $loginUserId, int $gender): int
    {
        $newGender = 0;//性别
        if ($gender == -1) {//首次打开
            $loginUser = (new User())->get_user($loginUserId);
            $newGender = $loginUser['gender'] == 1 ? 2 : ($loginUser['gender'] == 2 ? 1 : 0);//取异性
        } elseif ($gender >= 0) {
            $newGender = $gender;
        }

        return $newGender;
    }

    /**
     * 获取在线用户id
     *
     * @param int $loginUserId
     * @param int $gender
     * @return array
     */
    private function getOnlineUserIds(int $loginUserId, int $gender): array
    {
        $newGender = $this->getGender($loginUserId, $gender);
        if ($newGender == 1) {
            return $this->userModel->getOnlineManArr();//在线男性用户id
        } elseif ($newGender == 2) {
            return $this->userModel->getOnlineWomanArr();//在线女性用户id
        } else {
            return $this->userModel->getOnlineUserArr();//在线用户id
        }
    }

    /**
     * 初始化数据
     *
     * Created at 2021/10/20 18:30
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @return bool
     */
    public function initOnlineUserCache()
    {
        $this->userModel = new User();
        $this->roomUserModel = new RoomUser();
        $this->trendsModel = new Trends();
        $this->userOrigamiModel = new UserOrigami();
        $this->userTagService = new UserTagServices();
        $this->meetModel = new Meet();
        $userIds = $this->userModel->getOnlineUserArr();//在线用户id
        foreach ($userIds as $userId) {
            $userInfo = $this->getMeetUserInfo($userId, $userId);
            $this->meetModel->setOnlineUserLevelCache($userInfo['level'], $userId);
            echo $userId . ',done' . PHP_EOL;
        }

        return true;
    }
}